﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.SQLite;

namespace festivalDatabase
{
    /// <summary>
    /// This class sets up the Edit Music Festival GUI and creates it so that the user may change many aspects of
    /// the music festival.
    /// </summary>
    public partial class editMusicFestival : userInterface
    {
        /// <summary>
        /// Creates the GUI by taking in the tables file as well as the ID for the current festival.
        /// </summary>
        /// <param name="db"> database tables file </param>
        /// <param name="currFest"> integer which represents the current festival ID </param>
        public editMusicFestival(dbAccessor db, int currFest)
        {
            InitializeComponent();
            setIcon();
            dbAccess = db;
            festivalTypeComboBox.Items.Add("Music");
            festivalTypeComboBox.Items.Add("Art");
            currentFestivalID = currFest;
            loadFestivalInfo();
        }

        /// <summary>
        /// Queries the database and sets the text fields into the actual database. 
        /// It sends the ID, name, start and end dates, location, and festival type
        /// to the database
        /// </summary>
        private void loadFestivalInfo()
        {
            SQLiteCommand query = dbAccess.getCommand();
            query.CommandText = "SELECT * " +
                                "FROM festival " +
                                "WHERE id = @Id;";
            query.Parameters.Add("@Id", DbType.Int16);
            query.Parameters["@Id"].Value = currentFestivalID;

            DataTable currFest = dbAccess.executeQuery(query);
            DataRow currentFestival = currFest.Rows[0];

            festivalIDMaskedTextBox.Text = currentFestival["id"].ToString();
            festivalNameTextBox.Text = currentFestival["name"].ToString();
            string start = currentFestival["start_date"].ToString();
            if (start.Length > 0)
                startDateMaskedTextBox.Text = formatDateStringForDisplay(start);
            string end = currentFestival["end_date"].ToString();
            if (end.Length > 0)
                endDateMaskedTextBox.Text = formatDateStringForDisplay(end);
            locationTextBox.Text = currentFestival["location"].ToString();
            festivalTypeComboBox.Text = currentFestival["festival_type"].ToString();
        }

        /// <summary>
        /// Handles the events which occur when the edit music festival button is clicked, which has to pass several tests first
        /// before advancing on to actually edit the festival details
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void editMusicFestivalButton_Click(object sender, EventArgs e)
        {
            errorProvider.Clear();
            successLabel.Visible = false;

            if (verifyValidStartDate())
            {
                if (verifyValidEndDate())
                {
                    if (festivalTypeComboBox.Text != "Music" && festivalTypeComboBox.Text != "Art")
                        errorProvider.SetError(festivalTypeComboBox, "Invalid festival type; please select a type from the dropdown.");
                    else
                    {
                        updateFestival();
                        successLabel.Visible = true;
                        this.Close();
                        System.Windows.Forms.MessageBox.Show("Festival updated.");
                    }
                }
                else
                    errorProvider.SetError(endDateMaskedTextBox, "Invalid end date. Please enter a valid date in the form mm/dd/yyyy and ensure date is after start date.");
            }
            else
                errorProvider.SetError(startDateMaskedTextBox, "Invalid start date. Please enter a valid date in the form mm/dd/yyyy.");
        }

        /// <summary>
        /// Verifies that the start date is in a valid form: 10 characters, valid month, and valid day.
        /// </summary>
        /// <returns> bool </returns>
        private bool verifyValidStartDate()
        {
            if (startDateMaskedTextBox.Text.Length == 10){
                try
                {
                    DateTime date = DateTime.Parse(startDateMaskedTextBox.Text.ToString());
                    if (date.Month > 12)
                        return false;
                    if (date.Day > 31)
                        return false;
                }
                catch
                {
                    return false;
                }
            }

            return true;
        }

        /// <summary>
        /// Verifies which that the end date is in a valid format: ten characters long and
        /// a valid month and date.
        /// </summary>
        /// <returns> bool </returns>
        private bool verifyValidEndDate()
        {
            if (endDateMaskedTextBox.Text.Length == 10)
            {
                try
                {
                    DateTime endDate = DateTime.Parse(endDateMaskedTextBox.Text.ToString());
                    DateTime startDate = DateTime.Parse(startDateMaskedTextBox.Text.ToString());

                    if (endDate.Month > 12)
                        return false;
                    if (endDate.Day > 31)
                        return false;
                    if (endDate.Month < startDate.Month && endDate.Year <= startDate.Year)
                        return false;
                    if (endDate.Month == startDate.Month && endDate.Year == startDate.Year)
                        if (endDate.Day < startDate.Day)
                            return false;
                }
                catch
                {
                    return false;
                }
            }

            return true;
        }

        /// <summary>
        /// Updates the festival database with SQL queries. It allows for edits to be made
        /// to the festival and sends the database an ID, name, dates, location, and festival
        /// type.
        /// </summary>
        private void updateFestival()
        {
            SQLiteCommand nonQuery = dbAccess.getCommand();

            nonQuery.CommandText = "UPDATE festival SET ";
            nonQuery.CommandText += "id=@Id";
            nonQuery.Parameters.Add("@Id", DbType.Int16);
            nonQuery.Parameters["@Id"].Value = currentFestivalID;
            if (festivalNameTextBox.Text.ToString() != "")
            {
                nonQuery.CommandText += ", name=@Name";
                nonQuery.Parameters.Add("@Name", DbType.String);
                nonQuery.Parameters["@Name"].Value = festivalNameTextBox.Text.ToString();
            }
            if (startDateMaskedTextBox.Text.Length == 10)
            {
                nonQuery.CommandText += ", start_date=@Start";
                nonQuery.Parameters.Add("@Start", DbType.DateTime);
                nonQuery.Parameters["@Start"].Value = DateTime.Parse(startDateMaskedTextBox.Text.ToString()).ToString();
            }
            if (endDateMaskedTextBox.Text.Length == 10)
            {
                nonQuery.CommandText += ", end_date=@End";
                nonQuery.Parameters.Add("@End", DbType.DateTime);
                nonQuery.Parameters["@End"].Value = DateTime.Parse(endDateMaskedTextBox.Text.ToString()).ToString();
            }
            if (locationTextBox.Text.ToString() != "")
            {
                nonQuery.CommandText += ", location=@Location";
                nonQuery.Parameters.Add("@Location", DbType.String);
                nonQuery.Parameters["@Location"].Value = locationTextBox.Text.ToString();
            }
            if (festivalTypeComboBox.SelectedIndex >= 0)
            {
                nonQuery.CommandText += ", festival_type=@Type";
                nonQuery.Parameters.Add("@Type", DbType.String);
                nonQuery.Parameters["@Type"].Value = festivalTypeComboBox.Text.ToString();
            }

            nonQuery.CommandText += " WHERE id = @Id;";
            dbAccess.executeNonQuery(nonQuery);
        }
    }
}
